###############################################################################
#                                                                             #
#    This file is part of the "ssbot" Python module.                          #
#    It is distributed under the MIT License. See LICENSE.txt for details.    #
#                                                                             #
###############################################################################

import os
import os.path

import ssutils


class Poller(object):
    def __init__(self, url, repo_name, remote_branch):
        ssutils.validate_name(repo_name)
        self.url = url
        self.workspace_path = os.path.join('poller_workspace')
        self.repo_name = repo_name
        self.remote_branch = remote_branch
        if not os.path.exists(self.workspace_path):
            os.mkdir(self.workspace_path)

    def poll(self):
        raise NotImplementedError()


class GitPoller(Poller):
    def __init__(self, url, repo_name, remote_branch):
        Poller.__init__(self, url, repo_name, remote_branch)
        self._repo_dir = os.path.join(self.workspace_path, repo_name)
        self._poller_status_file_name = os.path.join(
            self.workspace_path, '.%s_poller_status' % repo_name)
        with open(self._poller_status_file_name, 'w') as f:
            f.writelines(['<None cached yet>'])
        self._blamelist = []

    def _git_log_n(self, n):
        return ssutils.run_cmd(
            ['git', 'log', '-%d' % n, '--pretty=oneline'],
            self._repo_dir,
            'Unable to run "git log" in %s.' % self._repo_dir)

    def poll(self):
        if not os.path.exists(self.workspace_path):
            raise RuntimeError('Git poller workspace directory missing.')
        if not os.path.exists(self._repo_dir):
            ssutils.run_cmd(
                ['git', 'clone', self.url, self._repo_dir],
                None,
                'Unable to clone from %s.' % self.url)
            ssutils.run_cmd(['git', 'checkout', self.remote_branch],
                            self._repo_dir,
                            'Unable to checkout %s.' % self.remote_branch)
        ssutils.run_cmd(['git', 'pull', '--rebase'],
                        self._repo_dir,
                        'Unable to "git pull" in %s.' % self._repo_dir)
        log = self._git_log_n(1)
        sha = log[0].strip().split()[0]
        with open(self._poller_status_file_name, 'r') as f:
            last_commit_sha = f.readlines()[0].strip()
            
        if sha == last_commit_sha:
            return ([], sha)

        i = 1
        blamelist = []
        while True and last_commit_sha != '<None cached yet>':
            i += 1
            commits = self._git_log_n(i)
            if commits[-1].strip().split()[0] == last_commit_sha:
                blamelist = [c.split()[0] for c in commits[:-1]]
                break
        with open(self._poller_status_file_name, 'w') as f:
            f.writelines([sha + '\n'])
        return (blamelist, sha)
